package com.museyu.service;

import com.museyu.exception.GameException;
import com.museyu.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class GameService {
    private static final Logger logger = LoggerFactory.getLogger(GameService.class);
    private final Map<String, GameRoom> rooms = new ConcurrentHashMap<>();
    private final Map<String, String> sessionToPlayerId = new ConcurrentHashMap<>();
    private final Map<String, Player> players = new ConcurrentHashMap<>();
    private final AtomicInteger roomCounter = new AtomicInteger(1);
    private final Map<String, String> playerIdToSessionId = new ConcurrentHashMap<>();

    public Player getPlayerBySessionId(String sessionId) {
        String playerId = sessionToPlayerId.get(sessionId);
        if (playerId == null) {
            return null;
        }
        return players.get(playerId);
    }

    public GameRoom createRoom() {
        String roomId = String.format("R%03d", roomCounter.getAndIncrement());
        GameRoom room = new GameRoom(roomId);
        rooms.put(roomId, room);
        logger.info("创建新房间: {}", roomId);
        return room;
    }

    public Player joinRoom(String roomId, String playerName) {
        GameRoom room = rooms.get(roomId);
        if (room == null) {
            throw new RuntimeException("房间不存在");
        }
        if (room.getPlayers().size() >= 4) {
            throw new RuntimeException("房间已满");
        }
        if (room.getState() != GameRoom.GameState.WAITING) {
            throw new RuntimeException("游戏已经开始");
        }

        String playerId = UUID.randomUUID().toString();
        Player player = new Player(playerId, playerName);
        room.addPlayer(player);
        players.put(playerId, player);
        
        // 如果是第一个加入的玩家，设置为房主
        if (room.getPlayers().size() == 1) {
            room.setOwnerId(playerId);
            logger.info("设置房主: playerId={}, roomId={}", playerId, roomId);
        }
        
        logger.info("玩家加入房间: playerId={}, playerName={}, roomId={}, 当前房间人数={}", 
            playerId, playerName, roomId, room.getPlayers().size());
        return player;
    }

    public void setPlayerSessionId(String playerId, String sessionId) {
        sessionToPlayerId.put(sessionId, playerId);
        playerIdToSessionId.put(playerId, sessionId);
        logger.info("设置玩家会话映射: playerId={}, sessionId={}", playerId, sessionId);
    }

    public String getSessionIdByPlayerId(String playerId) {
        return playerIdToSessionId.get(playerId);
    }

    public void removePlayerSession(String sessionId) {
        String playerId = sessionToPlayerId.remove(sessionId);
        if (playerId != null) {
            playerIdToSessionId.remove(playerId);
            removePlayer(playerId);
            logger.info("移除玩家会话映射: sessionId={}", sessionId);
        }
    }

    public GameRoom getRoom(String roomId) {
        GameRoom room = rooms.get(roomId);
        if (room == null) {
            throw new IllegalArgumentException("房间不存在");
        }
        return room;
    }

    public GameState startGame(String roomId, String playerId) {
        GameRoom room = getRoom(roomId);
        if (room == null) {
            throw new RuntimeException("房间不存在");
        }
        
        Player player = getPlayer(playerId);
        if (player == null) {
            throw new RuntimeException("玩家不存在");
        }
        
        if (!room.getOwnerId().equals(playerId)) {
            throw new RuntimeException("只有房主可以开始游戏");
        }
        
        room.startGame();
        return convertToGameState(room);
    }

    public GameState becomeDealer(String roomId, String playerId) {
        GameRoom room = getRoom(roomId);
        if (room == null) {
            throw new RuntimeException("房间不存在");
        }
        
        Player player = getPlayer(playerId);
        if (player == null) {
            throw new RuntimeException("玩家不存在");
        }
        
        room.setDealerId(playerId);
        logger.info("设置庄家成功: roomId={}, playerId={}, playerName={}", roomId, playerId, player.getName());
        return convertToGameState(room);
    }

    public GameState drawCard(String roomId, String playerId) {
        GameRoom room = getRoom(roomId);
        if (room == null) {
            throw new RuntimeException("房间不存在");
        }
        
        Player player = getPlayer(playerId);
        if (player == null) {
            throw new RuntimeException("玩家不存在");
        }
        
        if (!room.getCurrentPlayerId().equals(playerId)) {
            throw new RuntimeException("不是你的回合");
        }
        
        room.drawCard(playerId);
        return convertToGameState(room);
    }

    public GameState skipTurn(String roomId, String playerId) {
        GameRoom room = getRoom(roomId);
        if (room == null) {
            throw new RuntimeException("房间不存在");
        }
        
        Player player = getPlayer(playerId);
        if (player == null) {
            throw new RuntimeException("玩家不存在");
        }
        
        if (!room.getCurrentPlayerId().equals(playerId)) {
            throw new RuntimeException("不是你的回合");
        }
        
        room.skipTurn(playerId);
        return convertToGameState(room);
    }

    public void removePlayer(String playerId) {
        Player player = players.remove(playerId);
        if (player != null) {
            for (GameRoom room : rooms.values()) {
                if (room.removePlayer(playerId)) {
                    logger.info("玩家 {} 离开房间 {}", player.getName(), room.getId());
                    
                    // 如果房间没有玩家了，删除房间
                    if (room.getPlayers().isEmpty()) {
                        rooms.remove(room.getId());
                        logger.info("房间 {} 已删除", room.getId());
                    }
                }
            }
        }
    }

    public void leaveRoom(String roomId, String playerId) {
        GameRoom room = rooms.get(roomId);
        if (room != null) {
            if (room.removePlayer(playerId)) {
                logger.info("玩家 {} 离开房间 {}", playerId, roomId);
                
                // 如果房间没有玩家了，删除房间
                if (room.getPlayers().isEmpty()) {
                    rooms.remove(roomId);
                    logger.info("房间 {} 已删除", roomId);
                }
            }
        }
    }

    private List<Card> createDeck() {
        List<Card> deck = new ArrayList<>();
        String[] suits = {"♠", "♥", "♣", "♦"};
        String[] values = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
        
        for (String suit : suits) {
            for (String value : values) {
                deck.add(new Card(suit, value));
            }
        }
        
        return deck;
    }

    private Player getPlayer(String playerId) {
        return players.get(playerId);
    }

    public GameState convertToGameState(GameRoom room) {
        GameState state = new GameState();
        state.setRoomId(room.getId());
        state.setState(room.getState().name());
        state.setCurrentPlayerId(room.getCurrentPlayerId());
        state.setDealerId(room.getDealerId());
        
        List<GameState.PlayerView> playerViews = room.getPlayers().stream()
            .map(p -> {
                GameState.PlayerView view = new GameState.PlayerView();
                view.setId(p.getId());
                view.setName(p.getName());
                view.setCards(p.getCards());
                view.setDealer(p.getId().equals(room.getDealerId()));
                view.setCurrentPlayer(p.getId().equals(room.getCurrentPlayerId()));
                view.setHasDrawn(p.hasDrawn());
                view.setPoints(p.getPoints());
                view.setRoomOwner(p.getId().equals(room.getOwnerId()));
                logger.info("构建玩家视图: playerId={}, name={}, isDealer={}, dealerId={}", 
                    p.getId(), p.getName(), view.isDealer(), room.getDealerId());
                return view;
            })
            .collect(Collectors.toList());
        
        state.setPlayers(playerViews);
        return state;
    }
} 